package cn.baiweigang.uu.api.future;

import cn.baiweigang.uu.api.BaseApi;
import cn.baiweigang.uu.enums.DirectionEnum;
import cn.baiweigang.uu.enums.OffsetEnum;
import cn.baiweigang.uu.model.AccountInfo;
import cn.baiweigang.uu.model.PositionInfo;
import cn.baiweigang.uu.model.TradeInfo;
import cn.baiweigang.uu.utils.LogUtil;
import cn.baiweigang.uu.utils.StringUtil;
import com.huobi.future.api.request.trade.ContractCancelallRequest;
import com.huobi.future.api.request.trade.ContractOpenordersRequest;
import com.huobi.future.api.request.trade.ContractOrderRequest;
import com.huobi.future.api.request.trade.LightningClosePositionRequest;
import com.huobi.future.api.response.trade.ContractCancelallResponse;
import com.huobi.future.api.response.trade.ContractOpenordersResponse;
import com.huobi.future.api.response.trade.ContractOrderResponse;
import com.huobi.future.api.response.trade.LightningClosePositionResponse;
import com.huobi.future.api.service.trade.TradeAPIServiceImpl;
import org.springframework.stereotype.Component;

@Component
public class TradeFutureApi extends BaseApi {
    private TradeAPIServiceImpl tradeAPIService;

    /**
     * 委托下单
     *
     * @param tradeInfo
     * @return
     */
    public boolean orderRequest(TradeInfo tradeInfo) {
        try {
            init(tradeInfo.getAccountName());
            ContractOrderRequest request = ContractOrderRequest.builder()
                    .symbol(tradeInfo.getSymbol().getCode())
                    .contractType(tradeInfo.getContractType().getCode())
                    .volume(tradeInfo.getVolume())
                    .price(tradeInfo.getPrice())
                    .direction(tradeInfo.getDirection() == DirectionEnum.BUY ?
                            com.huobi.future.api.enums.DirectionEnum.BUY : com.huobi.future.api.enums.DirectionEnum.SELL)
                    .offset(tradeInfo.getOffset() == OffsetEnum.OPEN ?
                            com.huobi.future.api.enums.OffsetEnum.OPEN : com.huobi.future.api.enums.OffsetEnum.CLOSE)
                    .leverRate(tradeInfo.getLeverRate())
                    .orderPriceType(tradeInfo.getOrderPriceType().getCode())
                    .build();
            ContractOrderResponse response =
                    tradeAPIService.contractOrderRequest(request);
            if (response != null && response.getData() != null) {
                ContractOrderResponse.DataBean dataBean = response.getData();
                tradeInfo.setOrderId(dataBean.getOrderId());
                tradeInfo.setOrdeIdStr(dataBean.getOrderIdStr());
                tradeInfo.setClientOrderId(dataBean.getClientOrderId() + "");
                LogUtil.logInfo("交割合约下单提交成功");
                return true;
            }
        } catch (Throwable e) {
            LogUtil.logError("下单异常 " + e.getMessage());
        }
        return false;
    }

    /**
     * 查询当前是否存在未成交的委托
     *
     * @return
     */
    public boolean isExistOpenRequest(AccountInfo accountInfo) {
        try {
            init(accountInfo.getAccountName());
            ContractOpenordersRequest request = ContractOpenordersRequest.builder()
                    .symbol(accountInfo.getSymbol().getCode())
                    .build();
            ContractOpenordersResponse response =
                    tradeAPIService.contractOpenordersRequest(request);
            LogUtil.logDebug(response);
            if (response != null && response.getData() != null &&
                    response.getData().getOrders() != null && response.getData().getOrders().size() > 0) {
                LogUtil.logInfo("交割合约 存在未成交的订单");
                LogUtil.logInfo(response.getData().getOrders());
                return true;
            }
        } catch (Throwable e) {
            LogUtil.logError("交割合约未成交的委托 查询异常 " + e.getMessage());
        }
        return false;
    }

    /**
     * 撤销所有委托单
     *
     * @param accountInfo
     * @return
     */
    public boolean cancelAllRequest(AccountInfo accountInfo) {
        try {
            init(accountInfo.getAccountName());
            ContractCancelallRequest request = ContractCancelallRequest.builder()
                    .symbol(accountInfo.getSymbol().getCode())
                    .build();
            ContractCancelallResponse response =
                    tradeAPIService.contractCancelallRequest(request);
            LogUtil.logDebug(response);
            if (response != null) {
                LogUtil.logInfo("撤销所有委托单提交成功");
                return true;
            }
        } catch (Throwable e) {
            LogUtil.logError("撤销委托单异常 " + e.getMessage());
        }
        return false;
    }

    /**
     * 闪电平仓
     *
     * @return
     */
    public boolean lightningClosePositionRequest(String accountName, PositionInfo positionInfo) {
        try {
            init(accountName);
            LightningClosePositionRequest request = LightningClosePositionRequest.builder()
                    .direction(positionInfo.getDirection() == DirectionEnum.BUY ? "sell" : "buy")
                    .volume(positionInfo.getAvailable())
                    .build();
            if (positionInfo.getContractCode() != null) {
                request.setContractCode(positionInfo.getContractCode().getCode());
            } else if (positionInfo.getContractType() != null) {
                request.setSymbol(positionInfo.getSymbol().getCode());
                request.setContractType(positionInfo.getContractType().getCode());
            }
            LightningClosePositionResponse response =
                    tradeAPIService.lightningClosePositionRequest(request);
            if (response != null && response.getData() != null &&
                    StringUtil.isNotBlank(response.getData().getOrderIdStr())) {
                LogUtil.logInfo("交割合约 闪电平仓下单成功");
                return true;
            }
        } catch (Throwable e) {
            LogUtil.logError("交割合约 闪电平仓异常 " + e.getMessage());
        }
        return false;
    }

    private void init(String accountName) {
        if (tradeAPIService == null) {
            loadByAccountName(accountName);
            tradeAPIService = new TradeAPIServiceImpl(apiKeyInfo.getApiKey(), apiKeyInfo.getSecretKey());
        }
    }
}
